/*
 * @Author: zxc
 * @Date: 2020-08-02 11:16:29
 * @LastEditTime: 2020-08-02 12:41:32
 * @LastEditors: zxc
 * @Description: 双端队列
 */ 
const _dequeCount = new WeakMap()
const _dequeLowestCount = new WeakMap()
const _dequeItemsCount = new WeakMap()

class Deque{
  constructor(){
    _dequeCount.set(this, 0);
    _dequeLowestCount.set(this, 0);
    _dequeItemsCount.set(this, {});
  }
  //队列尾添加元素
  addBack(element) {
    let items = _dequeItemsCount.get(this)
    let count = _dequeCount.get(this)
    items[count] = element;
    _dequeCount.set(this,++count)
  }
  //在双端队列前添加新元素
  addFront(element){
    let lowestCount = _dequeLowestCount.get(this)
    let items = _dequeItemsCount.get(this)
    let count = _dequeCount.get(this)
    if(this.isEmpty()){
      this.addBack(element)
    } else if(lowestCount > 0){
      lowestCount--;
      items[lowestCount] = element;
      _dequeLowestCount.set(this,lowestCount)
    } else {
      for(let i = count;i>0;i--) {
        items[i] = items[i-1]
      }
      items[0] = element
      _dequeCount.set(this,++count)
      _dequeLowestCount.set(this,0)
    }
  }
  //队列前端移除
  removeFront(){
    if (this.isEmpty()) {
      throw new Error('队列为空')
    }
    let items = _dequeItemsCount.get(this)
    let lowestCount = _dequeLowestCount.get(this)
    const result = items[lowestCount]
    delete items[lowestCount]
    _dequeLowestCount.set(this,++lowestCount)
    return result;
  }
  //队列后端移除
  removeBack() {
    if (this.isEmpty()) {
      throw new Error('队列为空')
    }
    let count = _dequeCount.get(this)
    let items = _dequeItemsCount.get(this)
    let lowestCount = _dequeLowestCount.get(this)
    count--;
    const result = items[count];
    delete items[count];
    _dequeCount.set(this,count)
    return result;
  }
  //返回双端队列前端的第一个元素
  peekFront() {
    if (this.isEmpty()) {
     throw new Error('队列为空')
    }
    let items = _dequeItemsCount.get(this)
    let lowestCount = _dequeLowestCount.get(this)
    return items[lowestCount];
  }
  //返回双端队列后端的第一个元素
  peekBack() {
    if (this.isEmpty()) {
     throw new Error('队列为空')
    }
    let items = _dequeItemsCount.get(this)
    let count = _dequeCount.get(this)
    return items[count - 1];
  }
  //判空
  isEmpty() {
    return this.size() === 0;
  }
  //清空队列
  clear(){
    _dequeCount.set(this,0)
    _dequeLowestCount.set(this,0)
    _dequeItemsCount.set(this,{})
  }
  //队列大小
  size(){
    return _dequeCount.get(this) - _dequeLowestCount.get(this);
  }
  //toString
  toString(){
    if(this.isEmpty()) {
      throw new Error('队列为空')
    }
    let items = _dequeItemsCount.get(this)
    let lowestCount = _dequeLowestCount.get(this)
    let count = _dequeCount.get(this)
    let objString = `${items[lowestCount]}`
    for(let i = lowestCount+1;i<count; i++) {
      objString = `${objString},${items[i]}`
    }
    return objString;
  }
}

let deque = new Deque();
deque.addFront(4)
deque.addFront(3)
deque.addFront(1)
deque.addFront(1)
deque.addFront(9)
deque.addFront(5)
console.log(deque.removeBack())
console.log(deque.removeFront())
console.log(deque.peekBack())
console.log(deque.peekFront())
console.log(deque.toString())

export default Deque